package com.learning.spring.ioc.bean.annotation;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Map;

/**
 * ClassName: AnnotationBean
 * Description: 注解实现的 Bean 配置
 * Date: 2018/8/5 14:24 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
@Component(value = "annotationBean")
//@ComponentScan(basePackages = {"com.learning.spring.ioc.bean"}, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)})
@Getter
public class AnnotationBean {
    @Autowired
    @Qualifier(value = "injectionBean")
    private AnnotationInjectionBean injectionBean;

    void done() {
        injectionBean.done();
    }

    /**
     * spring 会将容器中所有类型为实现了 InjectionBean 接口的Bean 注入这个变量
     * 默认加载的顺序是不固定的，可以使用 @Order 注解实现加载顺序
     */
    @Autowired(required = false)
    private List<InjectionBean> list;

    /**
     * spring 会将实现了 InjectionBean 接口的Bean 注入Map
     * key 为 Bean 的名字
     * value 为所有实现了 InjectionBean 的 Bean
     */
    @Autowired(required = false)
    private Map<String, InjectionBean> map;

    @Autowired
    @Lazy
    private AnnotationInjectionBean3 annotationInjectionBean3;

}

interface InjectionBean {
    void done();
}

@Component(value = "injectionBean")
@Order(value = 1)
class AnnotationInjectionBean implements InjectionBean {

    public AnnotationInjectionBean() {
        System.out.println("AnnotationInjectionBean 被实例化了");
    }

    @Override
    public void done() {
        System.out.println("调用了 AnnotationInjectionBean.done() 方法");
    }
}

@Component(value = "injectionBean2")
@Order(value = 2)
class AnnotationInjectionBean2 implements InjectionBean {

    public AnnotationInjectionBean2() {
        System.out.println("AnnotationInjectionBean2 被实例化了");
    }

    @Override
    public void done() {
        System.out.println("调用了 AnnotationInjectionBean2.done() 方法");
    }
}

@Component(value = "injectionBean3")
@Order(value = 3)
@Lazy
class AnnotationInjectionBean3 implements InjectionBean {

    public AnnotationInjectionBean3() {
        System.out.println("AnnotationInjectionBean3 被实例化了");
    }

    @Override
    public void done() {
        System.out.println("调用了 AnnotationInjectionBean3.done() 方法");
    }

    /**
     * 注解可以标注多个方法
     */
    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct 注解标注初始化方法");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("@PreDestroy 注解标注销毁方法");
    }

}